package main

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"os"
)

type Application1 struct {
	Accept               string `json:"accept"`
	Appid                string `json:"appid"`
	Body                 string `json:"body"`
	BytesSent            string `json:"bytes_sent"`
	Client               string `json:"client"`
	Connection           string `json:"connection"`
	ContentType          string `json:"content_type"`
	Cookie               string `json:"cookie"`
	Domain               string `json:"domain"`
	Edition              string `json:"edition"`
	Encoding             string `json:"encoding"`
	Headers              string `json:"headers"`
	Host                 string `json:"host"`
	IpinfoCity           string `json:"ipinfo_city"`
	IpinfoDetail         string `json:"ipinfo_detail"`
	IpinfoDimensionality string `json:"ipinfo_dimensionality"`
	IpinfoIsp            string `json:"ipinfo_isp"`
	IpinfoLongitude      string `json:"ipinfo_longitude"`
	IpinfoNation         string `json:"ipinfo_nation"`
	IpinfoProvince       string `json:"ipinfo_province"`
	IpinfoState          string `json:"ipinfo_state"`
	Language             string `json:"language"`
	Method               string `json:"method"`
	Msec                 string `json:"msec"`
	Query                string `json:"query"`
	Referer              string `json:"referer"`
	RequestLength        string `json:"request_length"`
	RequestTime          string `json:"request_time"`
	Schema               string `json:"schema"`
	Status               string `json:"status"`
	Time                 string `json:"time"`
	Upstream             string `json:"upstream"`
	UpstreamConnectTime  string `json:"upstream_connect_time"`
	UpstreamResponseTime string `json:"upstream_response_time"`
	UpstreamStatus       string `json:"upstream_status"`
	Url                  string `json:"url"`
	UserAgent            string `json:"user_agent"`
	Uuid                 string `json:"uuid"`
	XForwardedFor        string `json:"x_forwarded_for"`
}

func convertJSONToCSV(source, destination string) error {
	// 2. Read the JSON file into the struct array
	sourceFile, err := os.Open(source)
	if err != nil {
		return err
	}
	// remember to close the file at the end of the function
	defer sourceFile.Close()

	var ranking []Application1
	if err := json.NewDecoder(sourceFile).Decode(&ranking); err != nil {
		return err
	}

	// 3. Create a new file to store CSV data
	outputFile, err := os.Create(destination)
	if err != nil {
		return err
	}
	defer outputFile.Close()

	// 4. Write the header of the CSV file and the successive rows by iterating through the JSON struct array
	writer := csv.NewWriter(outputFile)
	defer writer.Flush()

	for _, usance := range ranking {
		var row []string
		row = append(row, usance.Appid)
		row = append(row, usance.Body)
		row = append(row, usance.BytesSent)
		row = append(row, usance.Client)
		row = append(row, usance.Connection)
		row = append(row, usance.ContentType)
		row = append(row, usance.Cookie)
		row = append(row, usance.Domain)
		row = append(row, usance.Edition)
		row = append(row, usance.Encoding)
		row = append(row, usance.Headers)
		row = append(row, usance.Host)
		row = append(row, usance.IpinfoCity)
		row = append(row, usance.IpinfoDetail)
		row = append(row, usance.IpinfoDimensionality)
		row = append(row, usance.IpinfoIsp)
		row = append(row, usance.IpinfoLongitude)
		row = append(row, usance.IpinfoNation)
		row = append(row, usance.IpinfoProvince)
		row = append(row, usance.IpinfoState)
		row = append(row, usance.Language)
		row = append(row, usance.Method)
		row = append(row, usance.Msec)
		row = append(row, usance.Query)
		row = append(row, usance.Referer)
		row = append(row, usance.RequestLength)
		row = append(row, usance.RequestTime)
		row = append(row, usance.Schema)
		row = append(row, usance.Status)
		row = append(row, usance.Time)
		row = append(row, usance.Upstream)
		row = append(row, usance.UpstreamConnectTime)
		row = append(row, usance.UpstreamResponseTime)
		row = append(row, usance.UpstreamStatus)
		row = append(row, usance.Url)
		row = append(row, usance.UserAgent)
		row = append(row, usance.Uuid)
		row = append(row, usance.XForwardedFor)
		if err := writer.Write(row); err != nil {
			return err
		}
	}
	return nil
}

func main() {
	if err := convertJSONToCSV("./1.json", "./data.csv"); err != nil {
		fmt.Println(err)
		log.Fatal(err)
	}
}
